module test_pattern #(
    parameter TEST_DATA_LEN         = 16'd1472                  
)(
    input                           i_clk                               ,
    input                           i_rst                               ,
    input   [2 : 0]                 i_test_pattern                      ,
    output                          m_axis_tvalid                       ,
    output  [7 : 0]                 m_axis_tdata                        ,
    input                           m_axis_tready                       ,
    output                          m_axis_tlast                        ,
    output  [67: 0]                 m_axis_tuser                        ,
    input                           s_axis_tvalid                       ,
    input   [7 : 0]                 s_axis_tdata                        ,
    input                           s_axis_tlast                        ,
    input   [63: 0]                 s_axis_tuser                        
);

    localparam ST_IDLE              = 0                                 ;
    localparam ST_LOOP              = 1                                 ;
    localparam ST_SPEED             = 2                                 ;
    localparam ST_TCP_OPEN          = 3                                 ;
    localparam ST_TCP_LOOP          = 4                                 ;
    localparam ST_TCP_SPEED         = 5                                 ;
    localparam ST_TCP_CLOSE         = 6                                 ;
    localparam ST_END               = 7                                 ;

    logic   [2:0]                   test_pattern                        ;
    logic   [2:0]                   test_state                          ;
    logic                           tx_axis_tvalid                      ;
    logic   [7 : 0]                 tx_axis_tdata                       ;
    logic                           tx_axis_tlast                       ;
    logic   [67: 0]                 tx_axis_tuser                       ;
    logic   [31: 0]                 data_cnt                            ;
    logic                           tcp_once_flag                       ;

//     ila_32BIT ila_32BIT_test_patten (
// 	.clk(i_clk), // input wire clk


// 	.probe0({test_pattern, test_state,tx_axis_tvalid,tx_axis_tlast,tx_axis_tuser[67:64]}) // input wire [31:0] probe0
// );

    assign m_axis_tvalid = tx_axis_tvalid;
    assign m_axis_tdata = tx_axis_tdata; 
    assign m_axis_tlast = tx_axis_tlast; 
    assign m_axis_tuser = tx_axis_tuser;

    always_ff @( posedge i_clk ) begin
        if(i_rst) begin
            tx_axis_tvalid <= 0;
            tx_axis_tdata <= 0;
            tx_axis_tlast <= 0;
            tx_axis_tuser <= 0;
            data_cnt <= 0;
            test_pattern <= 0;
            tcp_once_flag <= 0;
            test_state <= ST_IDLE;
        end
        else  
            case (test_state)
                ST_IDLE :  begin
                    test_pattern <= i_test_pattern;
                    if(test_pattern == 1 && m_axis_tready) 
                        test_state <= ST_LOOP;
                    else if(test_pattern == 2 && m_axis_tready) 
                        test_state <= ST_SPEED;
                    else if(test_pattern == 3 && m_axis_tready) 
                        test_state <= ST_TCP_OPEN;
                    else if(test_pattern == 4 && m_axis_tready) 
                        test_state <= ST_TCP_CLOSE;
                    else 
                        test_state <= ST_IDLE;
                end

                ST_LOOP : begin
                    tx_axis_tvalid<= s_axis_tvalid;
                    tx_axis_tdata <= s_axis_tdata; 
                    tx_axis_tlast <= s_axis_tlast;
                    tx_axis_tuser <= {4'd0, s_axis_tuser}; 
                    if(tx_axis_tlast == 1)
                        test_state <= ST_END; 
                    else  
                        test_state <= ST_LOOP;
                end

                ST_SPEED : begin
                    if(tx_axis_tvalid)
                        tx_axis_tdata <= data_cnt[7:0]+1; 
                    else  
                        tx_axis_tdata <= 0;

                    tx_axis_tuser <= {4'd0, 16'd5001, 8'd192, 8'd168, 8'd7, 8'd100,TEST_DATA_LEN}; 

                    if( tx_axis_tvalid == 1 & m_axis_tready == 1 & data_cnt == TEST_DATA_LEN-1) 
                        tx_axis_tvalid <= 0;
                    else if(m_axis_tready) 
                        tx_axis_tvalid <= 1;
                    else 
                        tx_axis_tvalid<= tx_axis_tvalid;

                    if( tx_axis_tvalid == 1 & m_axis_tready == 1 & data_cnt == TEST_DATA_LEN-2 ) 
                        tx_axis_tlast <= 1;
                    else 
                        tx_axis_tlast<= 0;

                    if( tx_axis_tvalid) 
                        data_cnt <= data_cnt + 1;
                    else  
                        data_cnt <= data_cnt;

                    if(m_axis_tready == 0)
                        test_state <= ST_END;
                    else  
                        test_state <= ST_SPEED;
                end

                ST_TCP_OPEN : begin
                    tx_axis_tdata <= 8'h5a; 

                    if( tx_axis_tvalid & m_axis_tready) begin
                        tx_axis_tvalid <= 0;
                        tcp_once_flag <= tcp_once_flag;
                    end
                    else if(m_axis_tready & ~tcp_once_flag) begin
                        tx_axis_tvalid <= 1;
                        tcp_once_flag <= 1;
                    end
                    else begin
                        tx_axis_tvalid<= tx_axis_tvalid;
                        tcp_once_flag <= tcp_once_flag;
                    end

                    if(tx_axis_tlast & tx_axis_tvalid)
                        tx_axis_tlast <= 0;
                    if(m_axis_tready & ~tcp_once_flag) 
                        tx_axis_tlast <= 1;
                    else 
                        tx_axis_tlast<= 0;

                    tx_axis_tuser <= {2'd1,2'd1, 16'd5001, 8'd192, 8'd168, 8'd7, 8'd100,16'd1}; 

                    if(i_test_pattern == 7)
                        test_state <= ST_END;
                    else  
                        test_state <= ST_TCP_OPEN;
                    
                end

                ST_TCP_LOOP : begin
                    
                end

                ST_TCP_SPEED : begin
                    
                end

                ST_TCP_CLOSE : begin
                    tx_axis_tdata <= 8'h5a; 
                    if( tx_axis_tvalid & m_axis_tready) begin
                        tx_axis_tvalid <= 0;
                        tcp_once_flag <= tcp_once_flag;
                    end
                    else if(m_axis_tready & ~tcp_once_flag) begin
                        tx_axis_tvalid <= 1;
                        tcp_once_flag <= 1;
                    end
                    else begin
                        tx_axis_tvalid<= tx_axis_tvalid;
                        tcp_once_flag <= tcp_once_flag;
                    end

                    if(tx_axis_tlast & tx_axis_tvalid)
                        tx_axis_tlast <= 0;
                    if(m_axis_tready & ~tcp_once_flag) 
                        tx_axis_tlast <= 1;
                    else 
                        tx_axis_tlast<= 0;

                    tx_axis_tuser <= {2'd1,2'd2, 16'd5001, 8'd192, 8'd168, 8'd7, 8'd100,16'd1}; 

                    if(i_test_pattern == 7)
                        test_state <= ST_END;
                    else  
                        test_state <= ST_TCP_CLOSE;
                end

                ST_END : begin
                    tx_axis_tvalid<= 0;
                    tx_axis_tdata <= 0; 
                    tx_axis_tlast <= 0;
                    tx_axis_tuser <= tx_axis_tuser; 
                    tcp_once_flag <= 0;
                    data_cnt <= 0;
                    test_state <= ST_IDLE;
                   
                end

                default: test_state <= ST_IDLE;
            endcase
    end



    
   

          







endmodule